//====================================================================================================
// Filename:	TestApp.cpp
// Created by:	Peter Chan
//====================================================================================================

//====================================================================================================
// Includes
//====================================================================================================

#include "TestApp.h"

//====================================================================================================
// Class Definitions
//====================================================================================================

TestApp::TestApp()
	: mMouseX(-1)
	, mMouseY(-1)
	, mPanning(false)
{
	memset(mKeyStates, 0, sizeof(mKeyStates));
	//mTextureManager.Initialize(/*GraphicsSystem &gs*/); // Added
}

//----------------------------------------------------------------------------------------------------

TestApp::~TestApp()
{
}

//----------------------------------------------------------------------------------------------------

void TestApp::OnInitialize(u32 width, u32 height)
{
	mWindow.Initialize(GetInstance(), GetAppName(), width, height);
	HookWindow(mWindow.GetWindowHandle());

	mTimer.Initialize();

	mGraphicsSystem.Initialize(mWindow.GetWindowHandle(), false);
	SimpleDraw::Initialize(mGraphicsSystem);
	
	const u32 windowWidth = mGraphicsSystem.GetWidth();
	const u32 windowHeight = mGraphicsSystem.GetHeight();

	mCamera.Setup(Math::kPiByTwo, (f32)windowWidth / (f32)windowHeight, 0.01f, 1000.0f);

	mTextureManager.Initialize(mGraphicsSystem); // Added
	Texture* texture0 = mTextureManager.GetResource(L"../Engine/Images/checker.dds"); // L used make it it unicode normal
	Texture* texture1 = mTextureManager.GetResource(L"../Engine/Images/checker.dds"); // Will see it is already loaded, 

	SafeRelease(texture0); // Added
	SafeRelease(texture1);
}

//----------------------------------------------------------------------------------------------------

void TestApp::OnTerminate()
{
	mTextureManager.Terminate(); // Added

	SimpleDraw::Terminate();
	mGraphicsSystem.Terminate();
	mWindow.Terminate();
}

//----------------------------------------------------------------------------------------------------

bool TestApp::OnInput(const InputEvent& evt)
{
	bool handled = false;

	switch (evt.type)
	{
	case InputEvent::KeyDown:
		{
			mKeyStates[evt.value] = true;
			handled = true;
			
			if (mKeyStates[VK_ESCAPE])
			{
				PostQuitMessage(0);
			}
			else if (mKeyStates[VK_F1])
			{
				mGraphicsSystem.ToggleFullscreen();
			}
			//else if (mKeyStates[VK_SPACE])
			//{
			//	if (!panning)
			//	{
			//		//mMouseX = InputSystem::GetMouseScreenX(); // How to make this work? where is the instance of an inputsystem?
			//		mMouseY = evt.y;
			//		panning = true;
			//	}
			//}
		}
		break;
	case InputEvent::KeyUp:
		{
			mKeyStates[evt.value] = false;
			handled = true;

			if (VK_SPACE == evt.value)
			{
				mPanning = false;
			}
		}
		break;
	case InputEvent::MouseMove:
		{
			if (mPanning) // Added
			{
				if (mMouseX != -1 && mMouseY != -1)
				{
					f32 deltaX = (f32)(evt.x - mMouseX);
					f32 deltaY = (f32)(evt.y - mMouseY);
					mCamera.Yaw(deltaX);
					mCamera.Pitch(deltaY);
				}
				mMouseX = evt.x;
				mMouseY = evt.y;
				//mMouseX = evt.x * 0.1; // Funky effect to viewing the windown
				//mMouseY = evt.y * 0.1;
			}
			handled = true;
		}
		break;
	case InputEvent::MouseDown:
		{
			//mKeyStates[evt.value] = true;
			handled = true;
			if (evt.value == Mouse::LBUTTON) // Added
			{
				if (!mPanning)
				{
					mMouseX = evt.x;
					mMouseY = evt.y;
					mPanning = true;
				}
			}
		}
		break;
	case InputEvent::MouseUp:
		{
			if (evt.value == Mouse::LBUTTON) // Added
			{
				mPanning = false;
			}
			handled = true;
		}
		break;
	}

	return handled;
}

//----------------------------------------------------------------------------------------------------

void TestApp::OnUpdate()
{
	if (mWindow.HandleMessage())
	{
		mRunning = false;
	}
	else
	{
		// Update our time
		mTimer.Update();

		// Camera movement
		const float kMoveSpeed = 70.0f; // Default: 100
		const float kTurnSpeed = 5.0f; // Default: 5
		if (mKeyStates[VK_UP] || mKeyStates['W']) // Forward these to a manager in the future
		{
			if(mPanning)
			{
				mCamera.Walk(kMoveSpeed * mTimer.GetElapsedTime());
			}
			else
			{
				mCamera.Rise(kMoveSpeed * mTimer.GetElapsedTime());
			}
		}
		else if (mKeyStates[VK_DOWN] || mKeyStates['S'])
		{
			if(mPanning)
			{
				mCamera.Walk(-kMoveSpeed * mTimer.GetElapsedTime());
			}
			else
			{
				mCamera.Rise(-kMoveSpeed * mTimer.GetElapsedTime());
			}
			//mCamera.Walk(-kMoveSpeed * mTimer.GetElapsedTime());
		}
		else if (mKeyStates[VK_RIGHT] || mKeyStates['D'])
		{
			mCamera.Strafe(kMoveSpeed * mTimer.GetElapsedTime());
		}
		else if (mKeyStates[VK_LEFT] || mKeyStates['A'])
		{
			mCamera.Strafe(-kMoveSpeed * mTimer.GetElapsedTime());
		}
		
		// Render scene origional
		//mGraphicsSystem.BeginRender(Color::Black()); // Change background color here
		//
		//SimpleDraw::AddLine(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, Color::Red());
		//SimpleDraw::AddLine(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, Color::Green());
		//SimpleDraw::AddLine(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, Color::Blue());

		//SimpleDraw::AddAABB(-5.0f, -5.0f, -5.0f, 5.0f, 5.0f, 5.0f, Color::Cyan());
		//SimpleDraw::AddSphere(Math::Vector3(0.0f, 7.5f, 0.0f), 2.5f, Color::Magenta());
	
		//SimpleDraw::AddScreenRect(100.0f, 100.0f, 200.0f, 500.0f, Color::Magenta());
		//SimpleDraw::AddScreenCircle(150.0f, 300.0f, 50.0f, Color::Cyan());

		//SimpleDraw::Render(mCamera);

		//mGraphicsSystem.EndRender();

		// Render scene First try **************************************************
		mGraphicsSystem.BeginRender(Color::Black()); // Change background color here

		//u8 tempChangerPoint(rand() % 10);
		f32 tempChangerPoint(Random::GetF(0.0f, 10.0f)); // Slower????????????????????????????????????
		//f32 tempChanger((f32)(rand() % 45) + 5.0f + ((f32)tempChangerPoint * 0.1f)); // It works
		f32 tempChanger(Random::GetF(0.0f, 45.0f) + 5.0f + (tempChangerPoint * 0.1f));
		static f32 countingChanger(5.0f);
		static bool backTheOtherWay(false);

		SimpleDraw::AddLine(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, Color::Red());
		SimpleDraw::AddLine(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, Color::Green());
		SimpleDraw::AddLine(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, Color::Blue());

		SimpleDraw::AddAABB(-5.0f, -5.0f, -5.0f, 5.0f, 5.0f, 5.0f, Color::Cyan());
		//SimpleDraw::AddSphere(Math::Vector3(0.0f, 7.5f, 0.0f), 2.5f, Color::Magenta());
		SimpleDraw::AddSphere(Math::Vector3(countingChanger, 7.5f, 0.0f), 2.5f, Color::Magenta());

		//SimpleDraw::AddScreenRect(100.0f, 100.0f, 200.0f, 500.0f, Color::Magenta());
		SimpleDraw::AddScreenRect(100.0f, 100.0f, 201.5f, 501.5f, Color::Magenta()); // Make it so that the speaker fits inside the box properly
		//SimpleDraw::AddScreenCircle(150.0f, 300.0f, 50.0f, Color::Cyan());
		SimpleDraw::AddScreenCircle(150.0f, 300.0f, tempChanger, Color::Cyan());
		// Speaker randomly moving, makes noise?
		//u8 speakerPoint(rand() % 10);
		//f32 speaker((f32)(rand() % 3) + 42.0f + ((f32)speakerPoint * 0.1f));
		f32 speakerPoint(Random::GetF(0.0f, 10.0f));
		f32 speaker((f32)(Random::GetF(0.0f, 3.0f)) + 42.0f + (speakerPoint * 0.1f));
		SimpleDraw::AddScreenCircle(150.0f, 450.0f, speaker, Color::Cyan()); // Outer Cone
		SimpleDraw::AddScreenCircle(150.0f, 450.0f, (speaker * 0.3f), Color::Cyan()); // Inner Cone
		SimpleDraw::AddScreenCircle(150.0f, 450.0f, 50.0f, Color::Cyan()); // Outer Rim
		SimpleDraw::AddScreenCircle(150.0f, 450.0f, 49.0f, Color::Cyan()); // Inner Rim

		SimpleDraw::Render(mCamera);

		mGraphicsSystem.EndRender();

		if (backTheOtherWay)
		{
			if (countingChanger > -5.0f)
			{
				//--countingChanger;
				countingChanger -= 0.001f;
			}
			else
			{
				//++countingChanger;
				countingChanger += 0.001f;
				backTheOtherWay = false;
			}
		}
		else if (!backTheOtherWay)
		{
			if (countingChanger < 5.0f)
			{
				//++countingChanger;
				countingChanger += 0.001f;
			}
			else
			{
				//--countingChanger;
				countingChanger -= 0.001f;
				backTheOtherWay = true;
			}
		}
	}
}